package org.wak.action.scumm
{
	import org.wak.action.ActionsFactory;
	import org.wak.action.IActionController;
	import org.wak.action.actions.AdventureActions;
	import org.wak.action.actions.BaseAction;
	import org.wak.character.AdventureCharacter;
	import org.wak.gui.IAdventureGui;
	import org.wak.gui.events.GuiEvent;
	import org.wak.gui.scumm.ScummGui;
	import org.wak.main.AdventureMaster;
	import org.wak.main.PuzzleControllerBase;
	import org.wak.scene.events.SceneEvent;
	import org.wak.utils.IIterator;

	/**
	 * Action controller for the scumm adventure style 
	 * 
	 */	
	public class ActionControllerScumm implements IActionController
	{
		/**
		 * Character the current player's character.		 
		 */		
		protected var mPlayerChar:AdventureCharacter = null ; 
		
		/**
		 * Local reference to the Scumm Gui.		 
		 */	
		protected var mScummGui:ScummGui = null ;
		
		/**
		 *  Action id of the button selected in the scumm gui.
		 */		
		protected var mCurrentSelectedButtonId:String = "" ;
		
		/**
		 * The current active action. 
		 */		
		protected var mActiveAction:BaseAction = null ;
		
		/**
		 * IInteractable's name of a possible action's parameter. 
		 */		
		protected var mPotentialActionArgument:String = "" ;
		
		/**
		 * Default action of the last accepted  <code>mPotentialActionArgument</code> .
		 */		
		protected var mCurrentDefaulAction:String = "" ;
		
		/**
		 * Constructor 
		 * 
		 */		
		public function ActionControllerScumm()
		{
			mPlayerChar = AdventureMaster.CharactersMngr.GetCharacter( AdventureMaster.defaultPlayerCharacterId );
		}
		
		/**
		 * @inheritDoc
		 */		
		public function Initialize():void
		{
			var fAdventureGui:IAdventureGui = AdventureMaster.GuiMngr.adventureGui ;
			mScummGui = fAdventureGui as ScummGui ;
			
			if(mScummGui == null)
			{
				throw new Error("ActionControllerScumm. Can't Initialize null Scumm gui");
			}
			mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdWalkTo );
			mScummGui.SetFeedbackText( mActiveAction.GetText() );
			
		}

		/**
		 * @inheritDoc
		 */		
		public function OnSceneItemClick(event:SceneEvent):void
		{
			var fShiftPressed:Boolean = event.shiftKey ;
			
			// if the player's clicks on his avatar, just ignore it
			// and walk to that scene spot.
			if( (event.interactable == mPlayerChar.characterDisplay) || (event.interactable == null) )
			{
				mPlayerChar.MoveTo( event.sceneMouseX, event.sceneMouseY);
				mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdWalkTo );
				mScummGui.SetFeedbackText( mActiveAction.GetText() );
				return ;
			}
			
			// if the active action is ready, this ends here
			if(mActiveAction.isReady )
				return ;
				
			// if shift is pressed it counts as right click 
			// on the lucas adventures.
			if( fShiftPressed )
			{
				mActiveAction = ActionsFactory.CreateAction(event.interactable.defaultAction);
			}
			
			// if the active action is walk, then walk to the object's interaction point.
			if( mActiveAction.GetId() == AdventureActions.ActionIdWalkTo)
			{
				// and apply the object's animation behaviour when the walk is completed.
				var fBehave:Function = null ;
				if(event.interactable.interactionBehaviour != "")
				{
					fBehave = function():void
					{
						mPlayerChar.characterDisplay.SetAnimBehaviour(event.interactable.interactionBehaviour);
					}
				}
				mPlayerChar.MoveTo( event.interactable.interactionPointX, event.interactable.interactionPointY,fBehave);
				return ; 
			}
			
			mActiveAction.AddParameter(event.interactable);
			mScummGui.SetFeedbackText( mActiveAction.GetText() );
			
			if( mActiveAction.isReady )
			{
				var fMethodFound:Boolean = mActiveAction.CanExecute( AdventureMaster.ActionsMngr.GetPuzzleControllers() );
				// If the method can execute
				if( fMethodFound )
				{
					//trace("method found");
					// highlight the gui.
					mScummGui.enableHighlight = true ;
					// when the walk ends, execute the method for this action.
					var fOnWalkComplete:Function = function():void
					{
						
						mActiveAction.Execute( AdventureMaster.ActionsMngr.GetPuzzleControllers() );
					}
					mPlayerChar.MoveTo( event.interactable.interactionPointX, event.interactable.interactionPointY,fOnWalkComplete);
					
					
				}
				else
				{
					mScummGui.enableHighlight = true ;
					var fOnNoActionWalkComplete:Function = function():void
					{
						mScummGui.enableHighlight = false ;
						mPlayerChar.characterDisplay.SetAnimBehaviour(event.interactable.interactionBehaviour);
						mPlayerChar.Say(mActiveAction.GetNoActionText());
						mScummGui.ToggleSelectedButton( mActiveAction.GetId(), false );
						mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdWalkTo );
						mScummGui.SetFeedbackText( mActiveAction.GetText() );
					}
					mPlayerChar.MoveTo( event.interactable.interactionPointX, event.interactable.interactionPointY,fOnNoActionWalkComplete);
					
					
				}
			}
			//mActiveAction.AddSceneItemParameter(event.interactable);
			
			
		}
		
		/**
		 * @inheritDoc
		 */		
		public function OnSceneItemMouseOver(event:SceneEvent):void
		{
			//trace("OnSceneItemMouseOver");
			if( (event.interactable != null) && (event.interactable != mPlayerChar.characterDisplay) )
			{
				//trace("1")
				if(!mActiveAction.isReady)
				{
				//	trace("2");
					if( mActiveAction.TestParameter(event.interactable) )
					{
						mPotentialActionArgument = event.interactable.interactionName ;
						mScummGui.SetFeedbackText( mActiveAction.GetText() + " " + mPotentialActionArgument );
						mCurrentDefaulAction = event.interactable.defaultAction ;
						if( mActiveAction.GetId() == AdventureActions.ActionIdWalkTo )
							mScummGui.ToggleSelectedButton(mCurrentDefaulAction,true );
					}
				}
			}
		}
		
		/**
		 * @inheritDoc
		 */		
		public function OnSceneItemMouseOut(event:SceneEvent):void
		{
			//trace("scumm controller OnSceneItemMouseOut")
			if(!mActiveAction.isReady)
			{
				mPotentialActionArgument = "" ;
				mScummGui.SetFeedbackText( mActiveAction.GetText() );
				
				mScummGui.ToggleSelectedButton(mCurrentDefaulAction,false );
				//mCurrentDefaulAction = event.interactable.defaultAction ;
			}
		} 
		
		/**
		 * @inheritDoc
		 */		
		public function OnSceneSpaceClick(event:SceneEvent):void
		{
			mPlayerChar.MoveTo( event.sceneMouseX,event.sceneMouseY);
			mPotentialActionArgument = "" ;
			mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdWalkTo );
			mScummGui.ToggleSelectedButton( mCurrentSelectedButtonId, false);
			mScummGui.SetFeedbackText( mActiveAction.GetText() );
		}
		
		/**
		 * @inheritDoc
		 */		
		public function OnEnterScene(event:SceneEvent):void
		{
			mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdWalkTo );
			mScummGui.ToggleSelectedButton( mActiveAction.GetId(), false);
			mScummGui.SetFeedbackText( mActiveAction.GetText() );
			
			var fMethodName:String = "EnterScene"+event.sceneId ;
			var fPIt:IIterator = AdventureMaster.ActionsMngr.GetPuzzleControllers();
			
			var fMethodFound:Boolean = false ;
			var fPuz:PuzzleControllerBase = null ;
			while( fPIt.hasNext() )
			{
				fPuz = fPIt.next() as PuzzleControllerBase ;
				fMethodFound = fPuz.hasOwnProperty(fMethodName);
				if(fMethodFound)
				{
					fPuz[fMethodName](event.sceneId) ;
				}
			}
		}
		
		/**
		 * @inheritDoc
		 */		
		public function OnExitScene(event:SceneEvent):void
		{
			var fMethodName:String = "ExitScene"+event.sceneId ;
			var fPIt:IIterator = AdventureMaster.ActionsMngr.GetPuzzleControllers();
			
			var fMethodFound:Boolean = false ;
			var fPuz:PuzzleControllerBase = null ;
			while( fPIt.hasNext() )
			{
				fPuz = fPIt.next() as PuzzleControllerBase ;
				fMethodFound = fPuz.hasOwnProperty(fMethodName);
				if(fMethodFound)
				{
					fPuz[fMethodName](event.sceneId) ;
				}
			}
		}
		
		
		/**
		 * @inheritDoc
		 */		
		public function OnActionSelected(event:GuiEvent ):void 
		{
			if(mActiveAction.isReady)
				return ;
				
			if( mCurrentSelectedButtonId != "")
				mScummGui.ToggleSelectedButton( mCurrentSelectedButtonId, false );
				
			mCurrentSelectedButtonId = event.buttonId ;
			mScummGui.ToggleSelectedButton( event.buttonId, true );
			
			mActiveAction = ActionsFactory.CreateAction( event.buttonId );
			mScummGui.SetFeedbackText( mActiveAction.GetText() );
			
		}
		
		/**
		 * @inheritDoc
		 */		
		public function OnInventoryItemSelected( event:GuiEvent ):void 
		{
			if(mActiveAction.isReady)
				return ;
				
			mActiveAction.AddParameter(event.inventoryItem);
			mScummGui.SetFeedbackText( mActiveAction.GetText() );
			
			if( mActiveAction.isReady )
			{
				var fMethodFound:Boolean = mActiveAction.Execute( AdventureMaster.ActionsMngr.GetPuzzleControllers() );
				if( fMethodFound )
				{
					mScummGui.enableHighlight = true ;
				}
				else
				{
					// TODO: when the dialogs are complete the player should say something
					// like this doesn't work.
					mPlayerChar.Say( mActiveAction.GetNoActionText() );
					mScummGui.ToggleSelectedButton( mActiveAction.GetId(), false );
					mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdLookAt );
					mScummGui.SetFeedbackText( mActiveAction.GetText() );
				}
			}
		}
		
		/**
		 * @inheritDoc
		 */		
		public function OnInventoryItemOver( event:GuiEvent ):void 
		{
			if(mActiveAction.isReady)
				return ;
			//trace("Scumm controller OnInventoryItemOver")
			if( event.inventoryItem == null )
				return ;
				
			if( (mActiveAction.GetId() == AdventureActions.ActionIdWalkTo) || 
				(mActiveAction.GetId() == AdventureActions.ActionIdPickUp))
			{
				mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdLookAt );
				mScummGui.SetFeedbackText( mActiveAction.GetText() );
			}
			mCurrentDefaulAction = event.inventoryItem.defaultAction ;
			if( mActiveAction.GetId() == AdventureActions.ActionIdLookAt )
				mScummGui.ToggleSelectedButton(mCurrentDefaulAction,true );
			
			if( mActiveAction.TestParameter(event.inventoryItem) )
			{
				mPotentialActionArgument = event.inventoryItem.interactionName ;
				mScummGui.SetFeedbackText( mActiveAction.GetText() + " " + mPotentialActionArgument );
			}
		}
		
		/**
		 * @inheritDoc
		 */		
		public function OnInventoryItemOut( event:GuiEvent ):void 
		{
			if(mActiveAction.isReady)
				return ;
			//trace("Scumm controller OnInventoryItemOut")
			mPotentialActionArgument = "" ;
			mScummGui.SetFeedbackText( mActiveAction.GetText() );
			
			if(mActiveAction.GetId() == AdventureActions.ActionIdLookAt)
			{
				mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdWalkTo );
				mScummGui.SetFeedbackText( mActiveAction.GetText() );
			}
			
			mScummGui.ToggleSelectedButton(mCurrentDefaulAction,false );
			mCurrentDefaulAction = "" ;
			
		}
		
		/**
		 * @inheritDoc
		 */		
		public function EndOfAction():void
		{
			mScummGui.ToggleSelectedButton( mActiveAction.GetId(), false );
			mScummGui.enableHighlight = false ;
			mActiveAction = ActionsFactory.CreateAction( AdventureActions.ActionIdWalkTo );
			mScummGui.SetFeedbackText( mActiveAction.GetText() );
		}
		
		
		
	}
}